use rusqlite::ToSql;
use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ToSqlOutput, ValueRef};
use serde::{Deserialize, Serialize};

use crate::models::models::components::v2ray::basic_setting::ComponentV2rayBasicSetting;

#[derive(Debug, Default, Clone, Serialize, Deserialize, Eq, PartialEq)]
pub(crate) enum ComponentV2rayState {
    #[default]
    NotInstall,
    Installing,
    InstallFailed,
    NotRunning,
    Running,
    Failed,
}

impl ToSql for ComponentV2rayState {
    fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> {
        match *self {
            ComponentV2rayState::NotInstall => Ok(ToSqlOutput::Owned(rusqlite::types::Value::Text("NotInstall".to_string()))),
            ComponentV2rayState::Installing => Ok(ToSqlOutput::Owned(rusqlite::types::Value::Text("Installing".to_string()))),
            ComponentV2rayState::InstallFailed => Ok(ToSqlOutput::Owned(rusqlite::types::Value::Text("InstallFailed".to_string()))),
            ComponentV2rayState::NotRunning => Ok(ToSqlOutput::Owned(rusqlite::types::Value::Text("NotRunning".to_string()))),
            ComponentV2rayState::Running => Ok(ToSqlOutput::Owned(rusqlite::types::Value::Text("Running".to_string()))),
            ComponentV2rayState::Failed => Ok(ToSqlOutput::Owned(rusqlite::types::Value::Text("Failed".to_string()))),
        }
    }
}

impl FromSql for ComponentV2rayState {
    fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
        match value.as_str() {
            Ok("NotInstall") => Ok(ComponentV2rayState::NotInstall),
            Ok("Installing") => Ok(ComponentV2rayState::Installing),
            Ok("InstallFailed") => Ok(ComponentV2rayState::InstallFailed),
            Ok("NotRunning") => Ok(ComponentV2rayState::NotRunning),
            Ok("Running") => Ok(ComponentV2rayState::Running),
            Ok("Failed") => Ok(ComponentV2rayState::Failed),
            _ => Err(FromSqlError::InvalidType),
        }
    }
}

#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub(crate) struct ComponentV2rayInfo {
    // 版本号
    pub(crate) version: String,
    // 状态
    pub(crate) state: ComponentV2rayState,
    // 安装阶段
    pub(crate) install_stage: String,
    // 安装进度
    pub(crate) install_percent: u64,
    // 基础配置
    pub(crate) basic_setting: ComponentV2rayBasicSetting,
}